﻿using FakeItEasy;
using NJabber.Client.StanzaFactories;
using NUnit.Framework;
using System;
namespace NJabber.Client
{
    [TestFixture]
    public class XmppClientRuntimeTests
    {
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void Constructor_ServiceProviderIsNull_ThrowsException()
        {
            StandartClientRuntime runtime = new StandartClientRuntime(null);
        }

        [Test]
        public void RosterCache_ProviderHasService_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.RosterCache);
        }

        [Test]
        public void MessageStanzaFactory_ProviderHasServise_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.MessageStanzaFactory);
        }

        [Test]
        public void PresenceStanzaFactory_ProviderHasService_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.PresenceStanzaFactory);
        }

        [Test]
        public void RosterStanzaFactory_ProviderHasService_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.RosterStanzaFactory);
        }

        [Test]
        public void SubscriptionStanzaFactory_ProviderHasService_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.SubscriptionStanzaFactory);
        }

        [Test]
        public void PresenceStatusProvider_ProviderHasService_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.PresenceStatusProvider);
        }

        [Test]
        public void PresenceStatusUpdater_ProviderHasService_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.PresenceStatusUpdater);
        }

        [Test]
        public void Connection_ProviderHasService_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.Connection);
        }

        [Test]
        public void PresenceSubscriptionRegistry_ProviderHasService_CallsGetService()
        {
            VerifyServiceQuery(runtime => runtime.SubscriptionRegistry);
        }

        private void VerifyServiceQuery<T>(Func<StandartClientRuntime, T> propertyReader)
        {
            IServiceProvider serviceProvider = A.Fake<IServiceProvider>();
            StandartClientRuntime runtime = new StandartClientRuntime(serviceProvider);
            A.CallTo(() => serviceProvider.GetService(typeof(T))).Returns(A.Fake<T>());

            T property = propertyReader(runtime);

            A.CallTo(() => serviceProvider.GetService(typeof(T))).MustHaveHappened();
        }
    }
}
